import numpy as np
import requests
import pandas as pd
import plotly.graph_objects as go
from IPython.display import Markdown, display


def getFeatures(X, cmap):
    return pd.DataFrame(X).replace(cmap).values.squeeze().tolist()


def predict(X, name, ds, svc_hostname, cluster_ip):
    formData = {"instances": X}
    headers = {"Host": svc_hostname}
    res = requests.post(
        "http://" + cluster_ip + "/v1/models/" + name + ":predict",
        json=formData,
        headers=headers,
    )
    if res.status_code == 200:
        return ds.target_names[np.array(res.json()["predictions"])[0]]
    else:
        print("Failed with ", res.status_code)
        return []


def explain(X, name, svc_hostname, cluster_ip):
    formData = {"instances": X}
    headers = {"Host": svc_hostname}
    res = requests.post(
        "http://" + cluster_ip + "/v1/models/" + name + ":explain",
        json=formData,
        headers=headers,
    )
    if res.status_code == 200:
        return res.json()
    else:
        print("Failed with ", res.status_code)
        return []


def show_bar(X, labels, title):
    fig = go.Figure(go.Bar(x=X, y=labels, orientation="h", width=[0.5]))
    fig.update_layout(
        autosize=False,
        width=700,
        height=300,
        xaxis=dict(range=[0, 1]),
        title_text=title,
        font=dict(family="Courier New, monospace", size=18, color="#7f7f7f"),
    )
    fig.show()


def show_feature_coverage(exp):
    data = []
    for idx, name in enumerate(exp["anchor"]):
        data.append(go.Bar(name=name, x=["coverage"], y=[exp["raw"]["coverage"][idx]]))
    fig = go.Figure(data=data)
    fig.update_layout(yaxis=dict(range=[0, 1]))
    fig.show()


def show_anchors(names):
    display(Markdown("# Explanation:"))
    display(Markdown("## {}".format(names)))


def show_examples(exp, fidx, ds, covered=True):
    if covered:
        cname = "covered_true"
        display(
            Markdown(
                "## Examples covered by Anchors: {}".format(exp["anchor"][0 : fidx + 1])
            )
        )
    else:
        cname = "covered_false"
        display(
            Markdown(
                "## Examples not covered by Anchors: {}".format(
                    exp["anchor"][0 : fidx + 1]
                )
            )
        )
    if "feature_names" in ds:
        return pd.DataFrame(
            exp["raw"]["examples"][fidx][cname], columns=ds.feature_names
        )
    else:
        return pd.DataFrame(exp["raw"]["examples"][fidx][cname])


def show_prediction(prediction):
    display(Markdown("## Prediction: {}".format(prediction)))


def show_row(X, ds):
    display(pd.DataFrame(X, columns=ds.feature_names))
